package com.example.finalwork2.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.finalwork2.entity.VehicleSignal;
import com.example.finalwork2.mapper.VehicleSignalMapper;
import com.example.finalwork2.service.VehicleSignalService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class VehicleSignalServiceImpl extends ServiceImpl<VehicleSignalMapper, VehicleSignal> implements VehicleSignalService {


    private final JedisPool jedisPool;
    private final ObjectMapper objectMapper;
    @Override
    public List<VehicleSignal> getLatestByVehicleId(String vehicleId, int missingCount) {
        return this.lambdaQuery()
                .eq(VehicleSignal::getVehicleId, vehicleId)
                .orderByDesc(VehicleSignal::getReportTime)
                .last("LIMIT " + missingCount)
                .list();
    }





    @Autowired
    public VehicleSignalServiceImpl(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
        this.objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
    }

    @Override
    public void saveVehicleSignals(List<VehicleSignal> signals) throws Exception {
        try (Jedis jedis = jedisPool.getResource()) {
            for (VehicleSignal signal : signals) {
                signal.setReportTime(LocalDateTime.now());

                String key = "vehicle:signal:" + signal.getVehicleId();
                long score = signal.getReportTime().toEpochSecond(ZoneOffset.UTC);

                String value = objectMapper.writeValueAsString(signal);
                jedis.zadd(key, score, value);
            }
        } catch (Exception e) {
            throw new RuntimeException("保存信号到Redis失败", e);
        }
    }


    @Override
    public List<VehicleSignal> getLatestSignals(String vehicleId, int limit) {
        String redisKey = "vehicle:signal:" + vehicleId;
        List<VehicleSignal> result = new ArrayList<>();

        try (Jedis jedis = jedisPool.getResource()) {
            List<String> jsonList = jedis.zrevrange(redisKey, 0, limit - 1);

            for (String json : jsonList) {
                try {
                    VehicleSignal signal = objectMapper.readValue(json, VehicleSignal.class);
                    result.add(signal);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        int missingCount = limit - result.size();

        if (missingCount > 0) {
            // 这里调用同类中的从数据库查询方法
            List<VehicleSignal> dbList = getLatestByVehicleId(vehicleId, missingCount);

            Set<Long> existingIds = result.stream()
                    .map(VehicleSignal::getId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());

            for (VehicleSignal signal : dbList) {
                if (!existingIds.contains(signal.getId())) {
                    result.add(signal);
                }
            }
        }

        return result;
    }

}
